﻿//Copyright 2011 - Jonathan Allen

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;

namespace Granite.Eventing
{
	/// <summary>
	/// A relayed event wraps a sender/event args pair so that it can be forwarded by another class.
	/// </summary>
	[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
	public static class RelayedEventArgs
	{
		/// <summary>
		/// Create a new relayed event from an existing event
		/// </summary>
		[Pure]
		public static RelayedEventArgs<T> Create<T>(object originalSender, T eventArgs) where T : EventArgs
		{
			if (eventArgs == null)
				throw new ArgumentNullException("eventArgs", "eventArgs is null.");
			Contract.EndContractBlock();

			return new RelayedEventArgs<T>(originalSender, eventArgs);
		}
	}

	/// <summary>
	/// A relayed event wraps a sender/event args pair so that it can be forwarded by another class.
	/// </summary>
	[Pure]
	public class RelayedEventArgs<T> : EventArgs where T : EventArgs
	{
		readonly T m_EventArgs;
		readonly object m_OriginalSender;

		/// <summary>
		/// Create a new relayed event from an existing event
		/// </summary>
		[Pure]
		public RelayedEventArgs(object originalSender, T eventArgs)
		{
			m_EventArgs = eventArgs;
			m_OriginalSender = originalSender;
		}

		/// <summary>
		/// The wrapped event args
		/// </summary>
		public T EventArgs
		{
			get
			{
				Contract.Ensures(Contract.Result<T>() != null);
				return m_EventArgs;
			}
		}

		/// <summary>
		/// The object that raised the origial event
		/// </summary>
		public object OriginalSender
		{
			get { return m_OriginalSender; }
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
		[ContractInvariantMethod]
		void ObjectInvariant()
		{
			Contract.Invariant(m_EventArgs != null);
		}
	}

}
